//工作者线程 - 浏览器可以在原始页面环境之外再分配一个完全独立的二级子环境。
//1.专用工作者线程  new Worker(xx.js);
//2.共享工作者线程 new ShareWorder(xx.js);


/*
 3.服务工作者线程 (service workder)

 在学习这章的时候，我了解到了一个叫PWA的东西(progressive web app),全称叫:渐进式web App
 感觉还蛮有趣的，不过它的权限和分配的运行内存应该和普通网页一样的，所以目前应该只能做点小的应用。

 PWA是一个技术栈，涉及的内容比较广泛,但核心貌似离不开service workder

 官方教程: https://web.dev/learn/pwa/
*/



//♾️服务工作者线程SW p822 以下代码以成功实践: https://new-king.com/card  (该页面支持离线和下载) 
/*
  参考链接:
  1. MDN(所有相关函数页面)
  2. https://www.bilibili.com/video/BV19P4y1r7At
  3. https://blog.csdn.net/weixin_44786530/article/details/130423307
*/

const CACHE_NAME = 'newking-card';
//缓存文件列表,fetch阶段需要push
const CACHE_LIST = [];


const getcacheObj = async () => {
    //caches.open创建一个缓存对象(Promise),参数是一个缓存名称  source:https://www.jianshu.com/p/c2d5548c7b82
    let cache = await caches.open(CACHE_NAME);

    //拓展:缓存的形式为Request对象数组，Request请求获取的响应数据将会按键值存储在缓存对象里。
    //有两个方法可以往缓存对象里添加数据：add 和 addAll(返回Promise)
    return cache.addAll(CACHE_LIST);
}


//安装阶段 - sw注册成功
//self相当于webworker线程的当前作用域
self.addEventListener('install', async (e) => {
    self.skipWaiting();

    //waitUntill接受一个promise (因为创建缓存对象可能会延迟)
    e.waitUntil( getcacheObj() )
})

//激活阶段 - 第一次安装sw/sw更新
//sw程序更新后,不会立刻触发激活事件,而是进入waiting状态 (触发更新的时机: 1、关闭浏览器一段时间 2、手动清除serviceworker 3、手动跳过waiting阶段:skipWaiting())
self.addEventListener('activate',(e)=>{
    //可以做一些更新缓存操作
    console.log('activate:', e);
})



//请求处理程序
const requestHandler = async (request) => {

        //caches.match 检查给定的Request 对象或 url 字符串是否是一个已存储的 Response 对象的 key. 这个方法针对 Response 返回一个 Promise 
        //https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage/match

        const response_c = await caches.match(request); //用await解决该期约
        if(!!response_c) return response_c;
           
        //正常请求
        const response = await fetch(request);
        if(!response || response.status !== 200) return response;

        console.log('缓存中没有,正常发起请求并缓存...');

        const res4Cache = response.clone();
        caches.open(CACHE_NAME).then((cache)=>{
            return cache.put(request,res4Cache);
        })

        return response;
        

}



//🧊Fetch(最关键的阶段) 监听浏览器所有fetch请求,对已经缓存的资源使用本地缓存响应
self.addEventListener('fetch',(e)=>{
    // respondWith 方法阻止浏览器默认的 fetch 操作, 参数: Response/Promise
    // https://developer.mozilla.org/zh-CN/docs/Web/API/FetchEvent/respondWith 
    e.respondWith( requestHandler(e.request) )
})





//其他支持api: notificationclick、notificationclose、message、push 有需要再了解

self.addEventListener('notificationclick',(e)=>{
    console.log("notificationclick: " ,e);
})

self.addEventListener('notificationclose',(e)=>{
    console.log("notificationclose: " ,e);
})



//还有很多细节没做，就当做学习和了解了，后续会试试Workbox这个工具来帮助我完善这个webworker